package com.jhclothing.inbound.service.impl;

import com.jhclothing.common.utils.DateUtils;
import com.jhclothing.inbound.domain.FabricInbound;
import com.jhclothing.inbound.mapper.FabricInboundMapper;
import com.jhclothing.inbound.service.IFabricInboundService;
import com.jhclothing.product.domain.Fabric;
import com.jhclothing.product.service.IFabricService;
import com.jhclothing.product.vo.FabricInventoryVo;
import com.jhclothing.product.vo.StatisticInOutVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 布料入库Service业务层处理
 *
 * @author zyp
 * @date 2024-04-25
 */
@Service
public class FabricInboundServiceImpl implements IFabricInboundService {
    @Autowired
    private FabricInboundMapper fabricInboundMapper;
    @Autowired
    private IFabricService fabricService;

    /**
     * 查询布料入库
     *
     * @param inboundId 布料入库主键
     * @return 布料入库
     */
    @Override
    public FabricInbound selectFabricInboundByInboundId(Long inboundId) {
        return fabricInboundMapper.selectFabricInboundByInboundId(inboundId);
    }

    /**
     * 查询布料入库列表
     *
     * @param fabricInbound 布料入库
     * @return 布料入库
     */
    @Override
    public List<FabricInbound> selectFabricInboundList(FabricInbound fabricInbound) {
        return fabricInboundMapper.selectFabricInboundList(fabricInbound);
    }

    /**
     * 统计一定时间内的布料入库数量
     */
    @Override
    public List<StatisticInOutVo> statisticFabricInboundNum(StatisticInOutVo statisticInOutVo) {
        return fabricInboundMapper.statisticFabricInboundNum(statisticInOutVo);
    }

    /**
     * 新增布料入库
     *
     * @param fabricInbound  布料入库
     * @return 结果
     */
    @Override
    @Transactional
    public int insertFabricInbound(FabricInbound fabricInbound) {
        Fabric fabric = fabricService.selectFabricByFabricId(fabricInbound.getFabricId());
        BigDecimal fabricInventory = fabric.getNowInventory().add(fabricInbound.getInboundNum());
        fabricService.updateFabricInventory(fabricInbound.getFabricId(), fabricInventory);
        fabricInbound.setCreateTime(DateUtils.getNowDate());
        return fabricInboundMapper.insertFabricInbound(fabricInbound);
    }

    /**
     * 修改布料入库
     *
     * @param fabricInbound 布料入库
     * @return 结果
     */
    @Override
    @Transactional
    public String updateFabricInbound(FabricInbound fabricInbound) {
        // 上次入库信息
        FabricInbound originInbound = this.selectFabricInboundByInboundId(fabricInbound.getInboundId());
        BigDecimal originInboundNum = originInbound.getInboundNum();

        // 当前入库布料数量
        Fabric fabric = fabricService.selectFabricByFabricId(fabricInbound.getFabricId());
        BigDecimal nowInventory = fabric.getNowInventory();

        // 本次入库布料类别与之前记录一致
        if (fabricInbound.getFabricId() == originInbound.getFabricId()) {
            BigDecimal fabricInventory = nowInventory.add(fabricInbound.getInboundNum()).subtract(originInboundNum);
            if (fabricInventory.compareTo(BigDecimal.ZERO) < 0) {
                return String.format("修改布料 %s 入库数量后，布料库存为负数，请重新选择入库数量", fabric.getFabricCodeAndName());
            }
            fabricService.updateFabricInventory(fabricInbound.getFabricId(), fabricInventory);
        } else { // 本次入库布料类别与之前记录不一致
            Fabric originFabric = fabricService.selectFabricByFabricId(originInbound.getFabricId());
            BigDecimal originFabricNewInventory = originFabric.getNowInventory().subtract(originInboundNum);
            if (originFabricNewInventory.compareTo(BigDecimal.ZERO) < 0) {
                return String.format("修改入库的布料编码后，原布料库 %s 的库存为负数，请先确认原布料库的库存数量",
                        originFabric.getFabricCodeAndName());
            }
            fabricService.updateFabricInventory(originFabric.getFabricId(), originFabricNewInventory);
            fabricService.updateFabricInventory(fabricInbound.getFabricId(), fabric.getNowInventory().add(fabricInbound.getInboundNum()));
        }
        fabricInbound.setUpdateTime(DateUtils.getNowDate());
        fabricInboundMapper.updateFabricInbound(fabricInbound);
        return "SUCCESS";
    }

    /**
     * 批量删除布料入库
     *
     * @param inboundIds 需要删除的布料入库主键
     * @return 结果
     */
    @Override
    @Transactional
    public String deleteFabricInboundByInboundIds(Long[] inboundIds) {
        List<FabricInventoryVo> fabricInventoryVoList = new ArrayList<>();
        for (Long inboundId : inboundIds) {
            FabricInbound fabricInbound = this.selectFabricInboundByInboundId(inboundId);
            Fabric fabric = fabricService.selectFabricByFabricId(fabricInbound.getFabricId());
            BigDecimal fabricInventory = fabric.getNowInventory().subtract(fabricInbound.getInboundNum());
            if (fabricInventory.compareTo(BigDecimal.ZERO) < 0) {
                return String.format("删除当前入库信息后，布料 %s 库存为负数，无法删除当前入库信息", fabric.getFabricCodeAndName());
            }
            fabricInventoryVoList.add(new FabricInventoryVo(fabric.getFabricId(), fabricInventory));
        }

        for (FabricInventoryVo fabricInventoryVo : fabricInventoryVoList) {
            fabricService.updateFabricInventory(fabricInventoryVo.getFabricId(), fabricInventoryVo.getFabricInventory());
        }
        fabricInboundMapper.deleteFabricInboundByInboundIds(inboundIds);
        return "SUCCESS";
    }

    /**
     * 删除布料入库信息
     *
     * @param inboundId 布料入库主键
     * @return 结果
     */
    @Override
    @Transactional
    public String deleteFabricInboundByInboundId(Long inboundId) {
        FabricInbound FabricInbound = this.selectFabricInboundByInboundId(inboundId);
        Fabric fabric = fabricService.selectFabricByFabricId(FabricInbound.getFabricId());
        BigDecimal fabricInventory = fabric.getNowInventory().subtract(FabricInbound.getInboundNum());
        if (fabricInventory.compareTo(BigDecimal.ZERO) < 0) {
            return String.format("删除当前入库信息后，布料 %s 库存为负数，无法删除当前入库信息", fabric.getFabricCodeAndName());
        }
        fabricService.updateFabricInventory(FabricInbound.getFabricId(), fabricInventory);
        fabricInboundMapper.deleteFabricInboundByInboundId(inboundId);
        return "SUCCESS";
    }
}
